package com.zxl.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxl.constants.ExceptionMsg;
import com.zxl.entity.OrderDetail;
import com.zxl.exception.OrderException;
import com.zxl.feign.AddressFeign;
import com.zxl.feign.CarFeign;
import com.zxl.feign.StockFeign;
import com.zxl.intecepter.DataSourceInterceptor;
import com.zxl.mapper.OrderMapper;
import com.zxl.service.IOrderDetailService;
import com.zxl.service.IOrderService;
import com.zxl.entity.Order;
import com.zxl.utils.ExecutorUtils;
import com.zxl.utils.StringUtils;
import com.zxl.vo.Address;
import com.zxl.vo.Car;
import com.zxl.vo.OrderParam;
import com.zxl.vo.StockReduce;
import io.netty.util.concurrent.CompleteFuture;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @packageName com.zxl.service.impl
 * @ClassName
 * @Author zxl
 * @Description //TODO
 * @date
 **/
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private CarFeign carFeign;

    @Autowired
    private AddressFeign addressFeign;

    @Autowired
    private IOrderDetailService orderDetailService;
    @Autowired
    private StringUtils stringUtils;

    @Autowired
    private DataSourceInterceptor interceptor;
    @Autowired
    private StockFeign stockFeign;


    @Transactional
    public Boolean add(Integer uid, OrderParam orderParam) {

        //获取xiancc
        ThreadPoolExecutor pool = ExecutorUtils.getExecutor();

        //根据用户Id得到要存到数据库的哪一个表中去
        String tableId = interceptor.getThreadLocal().get();
        CompletableFuture<Map<String, Object>> future1 = CompletableFuture.supplyAsync(() -> {
            String[] gids = orderParam.getGids();
            if (gids == null) {
                gids = new String[0];
            }
            //获取总价和购物车列表
            Map<String, Object> map = carFeign.carListByGidAndUid(uid, gids);
            //得到数据并进行处理
            List<Map<String, Object>> carList = (List<Map<String, Object>>) map.get("carList");
            List<Car> cars = JSON.parseArray(JSON.toJSONString(carList), Car.class);

            Map<String, Object> res = new HashMap<>();
            res.put("cars", cars);
            res.put("totalPrice", map.get("totalPrice"));
            return res;

        }, pool);

        //开启获取地址的线程
        CompletableFuture<Address> future2 = CompletableFuture.supplyAsync(() -> addressFeign.getById(orderParam.getAid()), pool);



        Map<String, Object> map = null;
        Address address = null;
        try {
            //得到future1的返回值
            map = future1.get();
            //根据future2返回值获取地址
            address = future2.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }


        Map<String, Object> finalMap = map;
        //减库存
        CompletableFuture<Boolean> future3 = CompletableFuture.supplyAsync(() -> {
            List<StockReduce> reduces = new ArrayList<>();
            for (Car car : (List<Car>) finalMap.get("cars")) {
                StockReduce stockReduce = new StockReduce(car.getGid(), car.getSum(), 1);
                reduces.add(stockReduce);
            }
            return stockFeign.reduce(reduces);
        }, pool);


        Boolean reduce = true;
        try {
            reduce = future3.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }


        if (!reduce) {
            throw new OrderException(ExceptionMsg.INVENTORY_SHORTAGE);
        }

        //生成订单编号
        String oid = stringUtils.createId(uid);
        //添加订单的线程
        Address finalAddress = address;
        CompletableFuture.runAsync(()->{
            //生成订单信息
            Order order = new Order();
            order.setId(oid);
            order.setUid(uid);
            order.setAddress(finalAddress.getAname());
            order.setUname(finalAddress.getUname());
            order.setPhone(finalAddress.getPhone());
            order.setPayType(1);
            order.setTotalPrice((Double) finalMap.get("totalPrice"));
            order.setStatus(1);
            order.setCreateTime(new Date());

            //添加订单信息到数据库
            baseMapper.insertOrder(order, tableId);
        },pool).thenRun(()->{
            //生成订单详情信息
            List<OrderDetail> orderDetails = new ArrayList<>();
            for (Car car : (List<Car>) finalMap.get("cars")) {
                OrderDetail orderDetail = new OrderDetail();
                orderDetail.setOid(oid);
                orderDetail.setGname(car.getGoods().getGname());
                orderDetail.setGpng(car.getGoods().getGpng());
                orderDetail.setGprice(car.getGoods().getGprice());
                orderDetail.setSum(car.getSum());
                orderDetail.setGtype(car.getGoods().getTypeid());
                orderDetail.setSubTotal(car.getSumPrice());
                orderDetail.setGid(car.getGid());
                orderDetail.setGdesc(car.getGoods().getGdesc());
                orderDetails.add(orderDetail);
            }
            //将订单详情数据存到数据库中
            orderDetailService.batchAddOrderDetail(orderDetails, tableId);
        });


        return true;

    }

    public Boolean add2(Integer uid, OrderParam orderParam) {
        /*

        String[] gids = orderParam.getGids();
        if (gids == null) {
            gids = new String[0];
        }
        Map<String, Object> map = carFeign.carListByGidAndUid(uid, gids);

        Address address = addressFeign.getById(orderParam.getAid());
        Order order = new Order();
        String oid = stringUtils.createId(uid);
        order.setId(oid);
        order.setUid(uid);
        order.setAddress(address.getAname());
        order.setUname(address.getUname());
        order.setPhone(address.getPhone());
        order.setPayType(1);
        order.setTotalPrice((Double) map.get("totalPrice"));
        order.setStatus(1);
        order.setCreateTime(new Date());

        //减库存
        List<StockReduce> reduces = new ArrayList<>();
        Boolean reduce = stockFeign.reduce(reduces);
        if (reduce) {
            throw new OrderException(ExceptionMsg.INVENTORY_SHORTAGE);
        }
        //添加订单信息到数据库
        //根据用户Id得到要存到数据库的哪一个表中去
        String tableId = interceptor.getThreadLocal().get();
        baseMapper.insertOrder(order, tableId);

        List<Map<String, Object>> carList = (List<Map<String, Object>>) map.get("carList");
        List<Car> cars = JSON.parseArray(JSON.toJSONString(carList), Car.class);

        List<OrderDetail> orderDetails = new ArrayList<>();
        for (Car car : cars) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOid(oid);
            orderDetail.setGname(car.getGoods().getGname());
            orderDetail.setGpng(car.getGoods().getGpng());
            orderDetail.setGprice(car.getGoods().getGprice());
            orderDetail.setSum(car.getSum());
            orderDetail.setGtype(car.getGoods().getTypeid());
            orderDetail.setSubTotal(car.getSumPrice());
            orderDetail.setGid(car.getGid());
            orderDetail.setGdesc(car.getGoods().getGdesc());
            orderDetails.add(orderDetail);
        }
        //将订单详情数据存到数据库中
        orderDetailService.batchAddOrderDetail(orderDetails, tableId);
        */
        return true;
    }


}
